#ifndef HIDDEVICE_H
#define HIDDEVICE_H

#include <QObject>
#include <QTimer>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/hid.h>
#include <linux/hiddev.h>
#include "hidusage.h"
#include <QMap>
#include <QSocketNotifier>
#include <libusb.h>
struct DeviceStatus{
    bool offhook : 1;
    bool mute    : 1;
    bool flash   : 1;
};

class HidDevice : public QObject
{
    Q_OBJECT
public:
    explicit HidDevice(int fd,QObject *parent = nullptr);
    ~HidDevice();

    /**
     * @brief 用于外部IO复用等回复read用
     */
    void handleRead();
    void sigRead();

    /**
     * @brief 获取内部fd，用于外部select等
     * @return 返回usb句柄
     */
    int getHandle(){return m_iHandle;}
    void UiClickProc(int role);
    const DeviceStatus stateCheck();

    void sendLED(int mode);

    /**
     * @brief 反转相关状态
     */
    void invertOffHook();
    void invertMute();
    void invertFlash();

    int init_libusb();
    int open_libusb();
    int open_libusb1();
    void open_hidapi();
    void open_devfs();
    void read_devfs();
    void read_volume();
    int16_t db2vol(float db);
    float vol2db(unsigned char data[2]);
signals:
    //this signal use for changing ui
    void sigStateChanged(int index);

    //send key and state(before keyPress)
    void sigKeyPress(int key,int state);
    void sigKeyRelease(int key);

    void sigTimerStart(int key);
private slots:
    void handleTimeOut();

private:
    bool getReportId();
    void sendVolumeEnd();
    int setRWFlags();

    int sendMaxVol();
    int sendMinVol();

private:
    int m_iHandle;

    unsigned int m_reportIdVolumeInc_In;
    unsigned int m_reportIdVolumeDec_In;

    unsigned int m_reportIdFlash_In;       //按下usb设备按钮时，设备发送给主机的
    unsigned int m_reportIdMute_In;
    unsigned int m_reportIdHookSwitch_In;
    unsigned int m_reportIdRing_In;

    unsigned int m_reportIdOffHook_Out;     //用于主机回复usb设备开启led
    unsigned int m_reportIdMute_Out;
    unsigned int m_reportIdFlash_Out;
    unsigned int m_reportIdRing_Out;


    bool m_stateOffHook;
    bool m_stateMute;
    bool m_stateFlash;

    struct hiddev_usage_ref m_ledOffHookEv; //开头遍历出来的usage结构体，包含usage_code等，便于后续直接发送给设备
    struct hiddev_usage_ref m_ledMuteEv;    //使用时直接修改value值发送即可
    struct hiddev_usage_ref m_ledFlashEv;
    struct hiddev_usage_ref m_ledRingEv;

    struct hiddev_usage_ref m_volumeUpEv;
    struct hiddev_usage_ref m_volumeDownEv;

    struct hiddev_report_info m_ledrinfo;

    QTimer timer;

    QSocketNotifier *m_pSockNotifier;

    libusb_device_handle *handle = NULL;
    libusb_context *ctx = NULL;
    unsigned char minvol[2] = {0};
    unsigned char maxvol[2] = {0};
};

#endif // HIDDEVICE_H
